package com.jiangjiang.eshop.wms.service;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiangjiang.eshop.customer.service.CustomerFacadeService;
import com.jiangjiang.eshop.inventory.updater.StockUpdaterFactory;
import com.jiangjiang.eshop.membership.service.MembershipService;
import com.jiangjiang.eshop.pay.service.PayService;
import com.jiangjiang.eshop.schedule.service.ScheduleService;
import com.jiangjiang.eshop.wms.constant.ReturnGoodsInputOrderApproveResult;
import com.jiangjiang.eshop.wms.constant.ReturnGoodsInputOrderStatus;
import com.jiangjiang.eshop.wms.constant.WmsStockUpdateEvent;
import com.jiangjiang.eshop.wms.convert.ReturnGoodsInputOrderConvert;
import com.jiangjiang.eshop.wms.dao.ReturnGoodsInputOrderMapper;
import com.jiangjiang.eshop.wms.domain.ReturnGoodsInputOrder;
import com.jiangjiang.eshop.wms.dto.ReturnGoodsInputOrderDTO;
import com.jiangjiang.eshop.wms.dto.ReturnGoodsInputOrderItemDTO;
import com.jiangjiang.eshop.wms.dto.ReturnGoodsInputOrderPutOnItemDTO;
import com.jiangjiang.eshop.wms.dto.ReturnGoodsInputOrderQuery;
import com.jiangjiang.eshop.wms.stock.WmsStockUpdater;
import com.jiangjiang.eshop.wms.stock.WmsStockUpdaterFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author Jianghaowen
 * @Date 2021/9/28
 * @Description: TODO
 * @Version V1.0
 **/
@Service
public class ReturnGoodsInputOrderService extends ServiceImpl<ReturnGoodsInputOrderMapper, ReturnGoodsInputOrder> {

    @Autowired
    private ReturnGoodsInputOrderConvert returnGoodsInputOrderConvert;
    @Autowired
    private ReturnGoodsInputOrderItemService returnGoodsInputOrderItemService;
    @Autowired
    private ReturnGoodsInputOrderPutOnItemService returnGoodsInputOrderPutOnItemService;
    @Autowired
    private CustomerFacadeService customerFacadeService;
    @Autowired
    private PayService payService;
    @Autowired
    private WmsStockUpdaterFactory stockUpdaterFactory;
    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private MembershipService membershipService;


    /**
     * 保存退货入库单数据
     *
     * @param dto 退货入库单数据
     * @return
     */
    public Boolean saveReturnGoodsInputOrder(ReturnGoodsInputOrderDTO dto) {
        ReturnGoodsInputOrder returnGoodsInputOrder = returnGoodsInputOrderConvert.convertDTO2Entity(dto);
        this.save(returnGoodsInputOrder);
        // 保存明细数据
        returnGoodsInputOrderItemService.saveBatchReturnGoodsInputOrderItems(returnGoodsInputOrder.getId(), dto.getItems());
        return true;
    }


    /**
     * 分页查询
     *
     * @param query 分页查询条件
     * @return 查询结果
     */
    public Page<ReturnGoodsInputOrderDTO> queryForPage(ReturnGoodsInputOrderQuery query) {
        Page<ReturnGoodsInputOrder> page = new Page<>(query.getPageNo(), query.getPageSize(), true);
        return returnGoodsInputOrderConvert.convertPage2DTO(this.getBaseMapper().selectPage(page, null));
    }

    /**
     * 根据退货入库单id查询退货入库单数据
     *
     * @param returnGoodsInputOrderId 退货入库单id
     * @return 查询结果
     */
    public ReturnGoodsInputOrderDTO queryById(Long returnGoodsInputOrderId) {
        ReturnGoodsInputOrderDTO dto = returnGoodsInputOrderConvert.convertEntity2DTO(this.getById(returnGoodsInputOrderId));
        dto.setItems(returnGoodsInputOrderItemService.queryByReturnGoodsInputOrderId(returnGoodsInputOrderId));
        return dto;
    }

    /**
     * “
     * 退货入库单更新
     *
     * @param dto 退货入库单
     * @return 处理结果
     */
    public Boolean updateReturnGoodsInputOrder(ReturnGoodsInputOrderDTO dto) {
        // 更新退货入库单
        LambdaUpdateWrapper<ReturnGoodsInputOrder> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(ReturnGoodsInputOrder::getId, dto.getId())
                .set(ReturnGoodsInputOrder::getArrivalTime, dto.getArrivalTime())
                .set(ReturnGoodsInputOrder::getStatus, dto.getStatus())
                .set(ReturnGoodsInputOrder::getGmtModified, new Date());

        this.update(wrapper);

        // 更新退货明细数据
        returnGoodsInputOrderItemService.updateBatchReturnGoodsInputOrderItem(dto.getItems());
        return true;
    }


    /**
     * 批量保存上架明细数据
     *
     * @param returnGoodsInputOrder 退货入库单数据
     * @throws Exception
     */
    public Boolean batchSavePutOnItems(ReturnGoodsInputOrderDTO returnGoodsInputOrder) throws Exception {
        List<ReturnGoodsInputOrderPutOnItemDTO> putOnItemList = returnGoodsInputOrder.getItems().stream()
                .map(ReturnGoodsInputOrderItemDTO::getPutOnItems)
                .flatMap(List::stream)
                .collect(Collectors.toList());

        returnGoodsInputOrderPutOnItemService.saveBatch(putOnItemList);
        return true;
    }

    /**
     * @param returnGoodsInputOrderId
     * @param status
     * @return
     */
    public Boolean updateStatus(Long returnGoodsInputOrderId, Integer status) {
        LambdaUpdateWrapper<ReturnGoodsInputOrder> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(ReturnGoodsInputOrder::getId, returnGoodsInputOrderId)
                .set(ReturnGoodsInputOrder::getStatus, status)
                .set(ReturnGoodsInputOrder::getGmtModified, new Date());
        return this.update(wrapper);
    }


    /**
     * 退货入库单提交申请
     *
     * @param returnGoodsInputOrderId 退货入库单id
     * @return c处理结果
     */
    public Boolean submitApprove(Long returnGoodsInputOrderId) {
        return updateStatus(returnGoodsInputOrderId, ReturnGoodsInputOrderStatus.WAIT_FOR_APPROVE);
    }


    /**
     * 退货入库单审核
     *
     * @param returnGoodsInputOrderId 退货入库单id
     * @param approveResult           审核结果
     * @return 处理结果
     */
    public Boolean approve(Long returnGoodsInputOrderId, Integer approveResult) throws Exception {
        if(ReturnGoodsInputOrderApproveResult.REJECTED.equals(approveResult)){
            return updateStatus(returnGoodsInputOrderId, ReturnGoodsInputOrderStatus.EDITING);
        }

        // 更新退货入库单状态
        ReturnGoodsInputOrderDTO returnGoodsInputOrder = queryById(returnGoodsInputOrderId);
        this.updateStatus(returnGoodsInputOrderId, ReturnGoodsInputOrderStatus.FINISHED);
        // 更新退货工单状态
        customerFacadeService.informReturnGoodsInputFinishedEvent(returnGoodsInputOrder.getReturnGoodsWorksheetId());
        // 退款
        Boolean refundResult = payService.refund(returnGoodsInputOrder);
        if(refundResult) {
            // 退款成功以后 变更 退货工单状态
            customerFacadeService.informRefundFinishedEvent(returnGoodsInputOrder.getReturnGoodsWorksheetId());
        }
        // 更新wms库存
        WmsStockUpdater stockUpdater = stockUpdaterFactory.create(
                WmsStockUpdateEvent.RETURN_GOODS_INPUT, returnGoodsInputOrder);
        stockUpdater.update();
        // 通知调度中心 完成退货入库事件发生了
        scheduleService.informReturnGoodsInputFinished(returnGoodsInputOrder);
        // 通知会员中心扣减积分
        membershipService.informFinishReturnGoodsEvent(returnGoodsInputOrder.getUserAccountId(),
                returnGoodsInputOrder.getPayableAmount());
        return true;
    }
}
